<?php
/**
 * Slince music finder library
 * @author Tao <taosikai@yeah.net>
 */
namespace Slince\MusicFinder\Netease;

use GuzzleHttp\Psr7\Request;
use Slince\MusicFinder\Entity\Album;
use Slince\MusicFinder\Entity\Singer;
use Slince\MusicFinder\Entity\Song;
use Slince\MusicFinder\Exception\SearchException;
use Slince\MusicFinder\HttpAwareFinder;

class Finder extends HttpAwareFinder
{
    const SEARCH_ENDPOINT = 'http://music.163.com/api/linux/forward';

    const SEARCH_REFERER = 'http://music.163.com/';

    const PLAY_URL = 'http://music.163.com/#/song?id={songId}';

    /**
     * {@inheritdoc}
     */
    public function search($name, $page = 1, $limit = 10)
    {
        $request = new Request('POST', static::SEARCH_ENDPOINT);
        $response = $this->getHttpClient()->send($request, [
            'form_params' => [
                'eparams' => static::encrypt([
                    'method' => 'POST',
                    'url' => 'http://music.163.com/api/cloudsearch/pc',
                    'params' => [
                        's' => $name,
                        'type' => 1,
                        'offset' => ($page - 1) * $limit,
                        'limit' => $limit
                    ]
                ])
            ]
        ]);
        $json = \GuzzleHttp\json_decode($response->getBody(), true);
        if ($json['code'] != 200) {
            throw new SearchException('Got a bad response');
        }
        return array_map(function($songData){
            return static::buildSong($songData);
        }, $json['result']['songs']);
    }

    /**
     * {@inheritdoc}
     */
    public function find($id)
    {
        $request = new Request('POST', static::SEARCH_ENDPOINT, [
            'Referer' => 'http://music.163.com/'
        ]);
        $response = $this->getHttpClient()->send($request, [
            'form_params' => [
                'eparams' => static::encrypt([
                    'method' => 'GET',
                    'url'    => 'http://music.163.com/api/song/detail',
                    'params' => array(
                        'id'  => $id,
                        'ids' => "[{$id}]"
                    )
                ])
            ]
        ]);
        file_put_contents(__DIR__ . '/res2', $response->getBody());
        echo $response->getBody();exit;
        $json = \GuzzleHttp\json_decode($response->getBody(), true);
        if ($json['code'] != 200) {
            throw new SearchException('Got a bad response');
        }
        return static::buildSong($songData);
    }

    public static function encrypt($data)
    {
        // 加密网易云音乐 api 参数
        $_key = '7246674226682325323F5E6544673A51';
        $data = json_encode($data);
        if (function_exists('openssl_encrypt')) {
            $data = openssl_encrypt($data, 'aes-128-ecb', pack('H*', $_key));
        } else {
            $_pad = 16 - (strlen($data) % 16);
            $data = base64_encode(mcrypt_encrypt(
                MCRYPT_RIJNDAEL_128,
                hex2bin($_key),
                $data.str_repeat(chr($_pad), $_pad),
                MCRYPT_MODE_ECB
            ));
        }
        return strtoupper(bin2hex(base64_decode($data)));
    }

    protected static function buildSong($songData)
    {
        $singer = new Singer($songData['ar'][0]['id'], $songData['ar'][0]['name']);
        $album = new Album($songData['al']['id'], $songData['al']['name'], $songData['al']['picUrl']);
        $playUrl = str_replace('{songId}', $songData['id'], static::PLAY_URL);
        return new Song($songData['id'], $songData['name'], null, $playUrl, $singer, $album);
    }
}